feat(bridge): add application-level SSR for React and Vue - #4869
feat(bridge): add application-level SSR for React and Vue#4869tonoizer wants to merge 16 commits into
Conversation
🦋 Changeset detectedLatest commit: 2e8c9a5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 53 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
✅ Deploy Preview for module-federation-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
2heal1
left a comment
There was a problem hiding this comment.
Leaving a few inline comments on the issues we discussed.
|
Pushed ed191ac — a small hardening pass from a full self-review of the branch:
Two API-level points worth a maintainer opinion (no code change here):
All 13 Playwright e2e specs and unit suites pass locally on this head. |
|
Pushed a hardening commit (37d9162) addressing three of the open discussion points from the description:
New unit tests in bridge-shared/bridge-react cover the fallback modes, timeout, DOM recovery, and ref-counting; a new |
|
Pushed f39a7d9 — architecture reset for the SSR foundation. Review identified that module-scoped hydration state is only correct for one remote mount. Rather than extend the reference-counted cache, this update replaces it with instance-scoped Bridge slots, explicit request/props input, and remote-owned dehydration. Each rendered remote now hydrates from its own container and state payload. The branch no longer rewrites React Router imports or fabricates data-router loader state. V1 supports explicit classic-router SSR through string adapters, while the shared result contract is stream-capable for a future non-breaking streaming adapter. First-class React Router data loaders remain out of scope for this PR. This also removes the unrelated Metro/schema drift and restores the valid |
d927242 to
c203d59
Compare
2915de3 to
2c3f1e5
Compare
Key the hydration registry by moduleName+instanceId, hydrate empty islands from markers, destroy React roots when mount DOM identity changes, require a registry for client references, and soft-cancel aborted Vue mounts so failed renders cannot leak remotes.
Claim registry snapshots before provider.render and fail them on cancel so SPA revisits cannot hydrate stale request-time state. KeepAlive reactivation falls back to CSR, and demo hosts stop re-seeding SSR refs after navigation. Co-authored-by: Cursor <cursoragent@cursor.com>
Guard the post-render abort path with destroyedRef so cleanup and the render queue cannot both call provider.destroy on the same DOM node. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
8813e97 to
dc506b9
Compare
Co-authored-by: Cursor <cursoragent@cursor.com>
Related: CSR meta-framework Bridge track (separate from this SSR PR)While this PR (#4869) owns Bridge SSR V1 (React/Vue; Nuxt/Modern adapters out of scope), a small CSR follow-up series lands the “one Bridge remote → Nuxt + React/Next hosts” path:
No overlap with the SSR island protocol here; these are additive host DX / routing fixes. |
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d1567be2b2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 088b3a4d42
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Description
Adds a deliberately narrow Bridge SSR V1 for React and Vue and hardens its hydration and lifecycle boundaries. A federated provider renders one buffered HTML island on the server; the host emits that HTML and its optional dehydrated state exactly once in an instance-scoped document slot, while serialized host context carries only a versioned module/instance reference.
Before React
hydrateRootor Vue application mount, the host installs a document hydration registry. The client resolves a reference to an immutable slot snapshot, validates its identity and direct-child structure, and consumes it once. Missing slots intentionally follow the existing CSR path; malformed, duplicated, or identity-conflicting slots fail with contextual hydration errors. After a successful consume, later SPA visits render through CSR rather than rehydrating stale server markup.The React adapter keeps Hook structure and callback/ref handling stable, serializes asynchronous renders, rejects late mounts, forwards asynchronous failures to the host boundary, and destroys nested providers exactly once with deferred React-root cleanup. The Vue adapter retains one app/router across ordinary prop changes using shallow-reactive props, remounts only for mount-critical router changes, waits for router readiness during hydration, and prevents cancelled mounts from being published.
The public SSR result remains limited to protocol version, module name, instance ID, HTML, and optional JSON state. A separate identity-only reference and result-to-reference boundary prevent HTML from entering host JSON. React Router aliasing remains the V1 integration model, enforced by server/browser build and bundle-exclusion checks.
The Rsbuild demo covers React host to Vue remote and Vue host to React remote in development and production. Tests cover the registry contract, HTML-safe serialization, reference conversion, React/Vue lifecycle behavior, no-JS output, hydration, deep links with query/hash, interactivity, multiple instances, and SPA revisit behavior.
Bridge SSR V1 intentionally does not provide a shared timeout or CSR fallback for remote load/render failures. A slow or broken remote can therefore fail the host response. Assets, status/header policy, streaming, React data routers, Nuxt, and Modern.js adapters remain out of scope.
Validation
pnpm install --frozen-lockfilepnpm exec prettier --check .pnpm run build:packagespnpm exec turbo run test --filter=@module-federation/bridge-shared --filter=@module-federation/bridge-react --filter=@module-federation/bridge-vue3pnpm run ci:local --only=e2e-bridge-ssrRelated Issue
Closes #4868
Types of changes
Checklist